package com.sghd.charge.module.order.entity;

import com.sghd.charge.module.model.ChannelType;
import com.sghd.charge.module.model.ChargeCode;
import com.sghd.charge.module.model.ChargeState;

import javax.persistence.*;
import java.util.Date;
import java.util.Objects;

/**
 * @author frank
 * 订单记录实体
 */
@Entity
@Table(catalog = "charge", indexes = {@Index(name = "index_transactionNumber", columnList = "transactionNumber"),
        @Index(name = "index_state", columnList = "state")})
public class Order {

    @Id
    /** 充值ID(server_order) */
    @Column(length = 100)
    private long id;
    /** 充值订单号 */
    /** 充值目标(由{@link ChargeType}决定含义) */
    private long playerId;
    /** 充值金额 */
    private int money;
    /** 充值订单状态 */
    @Enumerated(EnumType.STRING)
    @Column(length = 100)
    private ChargeState state;
    /** 下次重试时间 */
    private Date retryTime;
    /** 重试次数 */
    private int retry;
    /** 最后的充值回应状态码 */
    @Enumerated(EnumType.STRING)
    private ChargeCode code;
    /**渠道*/
    @Enumerated(EnumType.STRING)
    private ChannelType channel;
    /**商品id*/
    private String goodsId;
    /** 充值附加信息 */
    private String addition;
    /**额外信息*/
    private String attachment;
    /**开始时间*/
    private Date start;
    /**结束时间时间*/
    private Date complete;
    /**当前状态时间*/
    private Date current;
    /**所在服务器*/
    private int serverId;
    /**下单时的ip*/
    private String ip;
    /**交易流水号*/
    @Column(length = 100)
    private String transactionNumber;

    public void refund() {
        this.state = ChargeState.REFUND;
        this.current = new Date();
    }

    public void failure(ChargeCode code, String attachment) {
        this.state = ChargeState.FAIL;
        this.code = code;
        this.current = new Date();
        this.attachment = attachment;
    }

    public void prepareRetry(ChargeCode code, String attachment, Date nextRetryTime) {
        this.code = code;
        this.state = ChargeState.WAIT;
        this.retryTime = nextRetryTime;
        this.attachment = attachment;
    }

    /** 重试失败 */
    public void retryFailed(ChargeCode code, Date nextRetryTime) {
        this.retry++;
        this.code = code;
        this.retryTime = nextRetryTime;
    }

    public void success(ChargeCode code, String attachment) {
        this.code = code;
        this.state = ChargeState.COMPLETE;
        this.attachment = attachment;
        Date now = new Date();
        this.current = now;
        this.complete = now;
    }
    // Getter and Setter

    public String getAttachment() {
        return attachment;
    }

    public void setAttachment(String attachment) {
        this.attachment = attachment;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public String getAddition() {
        return addition;
    }

    public void setAddition(String addition) {
        this.addition = addition;
    }

    public Date getRetryTime() {
        return retryTime;
    }

    public void setRetryTime(Date retryTime) {
        this.retryTime = retryTime;
    }

    public int getRetry() {
        return retry;
    }

    public void setRetry(int retry) {
        this.retry = retry;
    }

    public ChargeCode getCode() {
        return code;
    }

    public void setCode(ChargeCode code) {
        this.code = code;
    }

    public ChargeState getState() {
        return state;
    }

    public void setState(ChargeState state) {
        this.state = state;
    }

    public ChannelType getChannel() {
        return channel;
    }

    public void setChannel(ChannelType channel) {
        this.channel = channel;
    }

    public long getPlayerId() {
        return playerId;
    }

    public void setPlayerId(long playerId) {
        this.playerId = playerId;
    }

    public String getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(String goodsId) {
        this.goodsId = goodsId;
    }

    public Date getStart() {
        return start;
    }

    public Date getComplete() {
        return complete;
    }

    public Date getCurrent() {
        return current;
    }

    public void setStart(Date start) {
        this.start = start;
    }

    public void setComplete(Date complete) {
        this.complete = complete;
    }

    public void setCurrent(Date current) {
        this.current = current;
    }

    public int getServerId() {
        return serverId;
    }

    public void setServerId(int serverId) {
        this.serverId = serverId;
    }

    public String getTransactionNumber() {
        return transactionNumber;
    }

    public void setTransactionNumber(String transactionNumber) {
        this.transactionNumber = transactionNumber;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Order order = (Order) o;
        return Objects.equals(id, order.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    // Static Method

    /** 构造方法 */
    public static Order valueOf(int serverId, long orderId, long playerId, int money, String goodsId, String ip, String addtion, ChannelType channelType) {
        Date now = new Date();
        Order result = new Order();
        result.serverId = serverId;
        result.id = orderId;
        result.playerId = playerId;
        result.money = money;
        result.state = ChargeState.START;
        result.goodsId = goodsId;
        result.addition = addtion;
        result.current = now;
        result.start = now;
        result.ip = ip;
        result.channel = channelType;
        return result;
    }

}